home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / Chaos53src.lha / chaos / src / PairingsAmi.c < prev    next >
C/C++ Source or Header  |  1994-11-19  |  16KB  |  555 lines

  1. /*  Chaos:            The Chess HAppening Organisation System    V5.3
  2.     Copyright (C)   1993    Jochen Wiedmann
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  
  19.     $RCSfile: PairingsAmi.c,v $
  20.     $Revision: 3.2 $
  21.     $Date: 1994/11/19 19:32:01 $
  22.  
  23.     This file contains functions that allow to set games by the
  24.     administrator. This is highly system dependent.
  25.  
  26.     Computer:    Amiga 1200            Compiler:    Dice 2.07.54 (3.0)
  27.  
  28.     Author:    Jochen Wiedmann
  29.         Am Eisteich 9
  30.       72555 Metzingen
  31.         Tel. 07123 / 14881
  32.         Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
  33. */
  34.  
  35.  
  36.  
  37. /*
  38.     The function GetSettings() should offer the user a list of players
  39.     and a list of games. Withdrawn players (which are indicated by the flag
  40.     TNFLAGSF_WITHDRAWN in their Flags field) should not appear. Players may
  41.     be included into the list of games by selecting them, so a game is set
  42.     by selecting the two opponents. If the number of selected players is odd,
  43.     the last player should get a point for free. (Of course this should be
  44.     rejected, if the number of players is odd!) Note, that selecting the
  45.     players doesn't mean deciding the colors. Chaos will select the colors
  46.     even for the set games, which allows to make the best choice.
  47.  
  48.     Inputs: user - TRUE, if the user should be allowed to set games
  49.  
  50.     Result: The number of games, that have been set. (Giving a point for
  51.         free to a player doesn't mean to set up a game, so if the user
  52.         has selected 5 players, the result will be 2.) -1 indicates, that
  53.         the user has cancelled.
  54.         The function has to indicate the selection by setting up the
  55.         Opponents field of the selected players or setting
  56.         GMFLAGSF_NOFIGHT in the GFlags field for the player who has got
  57.         a point for free.
  58.         The function is guaranteed, that all players Opponent fields are
  59.         initialized to NULL and the GFlags fiels is initialized with 0,
  60.         when the function is called. If you need flags, to mark special
  61.         players within the function, use TNFLAGSF_NOTDOWN.
  62.  
  63.     Note: I don't see a possibility to arrange this in a portable way. So
  64.       this is only ONE function. (But this allows me to use ALL the
  65.       advantages of MUI for the first time... :-)
  66. */
  67.  
  68.  
  69. #ifndef CHAOS_H
  70. #include "chaos.h"
  71. #endif
  72.  
  73.  
  74.  
  75.  
  76. #ifdef AMIGA
  77. /*
  78.     The set games are stored dynamically.
  79. */
  80. struct SetGame
  81. { struct MinNode node;
  82.   struct Player *plr1, *plr2;
  83.   char *gamestr;
  84.   int colors;
  85. };
  86. struct MinList *SetGames = NULL;
  87. static void *GmMem = NULL;
  88.  
  89.  
  90.  
  91.  
  92. /*
  93.     InitSetGames() initializes an empty list of games
  94.  
  95.     Result: TRUE, if successfull, FALSE otherwise
  96. */
  97. int InitSetGames(void)
  98.  
  99. { PutMemList (&GmMem);
  100.   if (!(SetGames = GetMem(&GmMem, sizeof(*SetGames))))
  101.   { return(FALSE);
  102.   }
  103.   NewList((struct List *) SetGames);
  104.   return(TRUE);
  105. }
  106.  
  107.  
  108.  
  109.  
  110. /*
  111.     SetPlayer adds one player to the list of set players
  112.  
  113.     Inputs: plr    - the player to be added
  114.         colors - TRUE, if the user wants to determine the colors, FALSE
  115.              otherwise
  116.         force  - FALSE, if the user should be asked for confirmation
  117.              in case both players had the same color in the last
  118.              two rounds, TRUE otherwise
  119.  
  120.     Result: TRUE, if successfull, FALSE otherwise
  121. */
  122. int SetPlayer(struct Player *plr, int force, int colors)
  123.  
  124. { struct SetGame *sg;
  125.   struct Game *gm;
  126.   int i;
  127.  
  128.   if (!SetGames  &&  !InitSetGames())
  129.   { return(FALSE);
  130.   }
  131.  
  132.   if (plr->Flags & TNFLAGSF_WITHDRAWN)
  133.   { ShowError((char *) GetChaosString(MSG_PLAYER_WITHDRAWN), plr->Name);
  134.     return(FALSE);
  135.   }
  136.   for (sg = (struct SetGame *) SetGames->mlh_Head;
  137.        sg->node.mln_Succ != NULL;
  138.        sg = (struct SetGame *) sg->node.mln_Succ)
  139.   { if (sg->plr1 == plr  ||  sg->plr2 == plr)
  140.     { ShowError((char *) GetChaosString(MSG_INVALID_PLAYER), plr->Name,
  141.         plr->Opponent->Name);
  142.       return(FALSE);
  143.     }
  144.   }
  145.  
  146.   /*
  147.       Check for valid game
  148.   */
  149.   sg = (struct SetGame *) SetGames->mlh_TailPred;
  150.   if (sg->node.mln_Pred != NULL  &&  sg->plr2 == NULL)
  151.   { for (i = 1, gm = plr->First_Game;  gm != NULL;
  152.      i++, gm = gm->Next)
  153.     { if (gm->Opponent == sg->plr1)
  154.       { ShowError((char *) GetChaosString(MSG_INVALID_GAME),
  155.           sg->plr1->Name, plr->Name, i);
  156.     return(FALSE);
  157.       }
  158.     }
  159.  
  160.     if ((i = sg->plr1->HowMuchWhiteLast) == plr->HowMuchWhiteLast  &&
  161.     (i >= 2  ||  i <= -2))
  162.     { if (!force  &&
  163.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLORS),
  164.                sg->plr1->Name, plr->Name,
  165.                (i == 2) ? GetChaosString(MSG_WHITE_OUTPUT) :
  166.                   GetChaosString(MSG_BLACK_OUTPUT)))
  167.       { return(FALSE);
  168.       }
  169.     }
  170.     else if (i >= 2  &&  colors)
  171.     { if (!force  &&
  172.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLOR),
  173.                sg->plr1->Name, GetChaosString(MSG_WHITE_OUTPUT)))
  174.       { return(FALSE);
  175.       }
  176.     }
  177.     else if (plr->HowMuchWhiteLast <= -2  &&  colors)
  178.     { if (!force  &&
  179.       !AskContinue((char *) GetChaosString(MSG_INVALID_COLOR),
  180.                plr->Name, GetChaosString(MSG_BLACK_OUTPUT)))
  181.       { return(FALSE);
  182.       }
  183.     }
  184.     sg->plr2 = plr;
  185.     sg->colors = colors;
  186.   }
  187.   else
  188.   { if (!(sg = GetMem(&GmMem, sizeof(*sg))))
  189.     { return(FALSE);
  190.     }
  191.     sg->plr1 = plr;
  192.     AddTail((struct List *) SetGames, (struct Node *) sg);
  193.   }
  194.   return(TRUE);
  195. }
  196.  
  197.  
  198.  
  199.  
  200. /*
  201.     The DoSetGames() function processes the list of set games and initializes
  202.     the players Opponent and GFlags fields.
  203.  
  204.     Result: Number of set games or -1, if an error occurred
  205. */
  206. static int DoSetGames(void)
  207.  
  208. { struct SetGame *sg;
  209.   int numplayers;
  210.   int result;
  211.  
  212.   struct Player *plr;
  213.  
  214.   if (SetGames == NULL)
  215.   { return(0);
  216.   }
  217.  
  218.   /*
  219.       Count the number of active players to see, if a one point bye is
  220.       needed.
  221.   */
  222.   for (numplayers = 0,  plr = (struct Player *) PlayerList.lh_Head;
  223.        plr->Tn_Node.ln_Succ != NULL;
  224.        plr = (struct Player *) plr->Tn_Node.ln_Succ)
  225.   { if (!(plr->Flags & TNFLAGSF_WITHDRAWN))
  226.     { numplayers++;
  227.     }
  228.   }
  229.  
  230.   /*
  231.       Check for invalid one point bye
  232.   */
  233.   sg = (struct SetGame *) SetGames->mlh_TailPred;
  234.   if (sg->node.mln_Pred != NULL  &&  sg->plr2 == NULL)
  235.   { if ((numplayers % 2)  ==  0)
  236.     { ShowError((char *) GetChaosString(MSG_INVALID_ONEPOINTBYE));
  237.       return(-1);
  238.     }
  239.     if (sg->plr1->Flags & TNFLAGSF_HADFREE)
  240.     { ShowError((char *) GetChaosString(MSG_HAD_ONEPOINTBYE),
  241.         sg->plr1->Name);
  242.       return(-1);
  243.     }
  244.   }
  245.  
  246.   for (result = 0, sg = (struct SetGame *) SetGames->mlh_Head;
  247.        sg->node.mln_Succ != NULL;
  248.        sg = (struct SetGame *) sg->node.mln_Succ)
  249.   { if (sg->plr2 == NULL)
  250.     { sg->plr1->GFlags = GMFLAGSF_NOFIGHT;
  251.     }
  252.     else
  253.     { sg->plr1->Opponent = sg->plr2;
  254.       sg->plr2->Opponent = sg->plr1;
  255.       sg->plr1->BoardNr = sg->plr2->BoardNr = result++;
  256.       if (sg->colors)
  257.       { sg->plr1->GFlags = GMFLAGSF_WHITE;
  258.       }
  259.     }
  260.   }
  261.   return(result);
  262. }
  263.  
  264.  
  265.  
  266.  
  267. /*
  268.     The following function is automagically called from MUI, if a game will
  269.     be displayed. (It's the game list's displayhook.)
  270. */
  271. SAVEDS ASM static LONG DispGameFunc(REG(a1) struct SetGame *setgame,
  272.                     REG(a2) char **array)
  273.  
  274. { *(array++) = setgame->plr1->Name;
  275.   *(array++) = setgame->plr2  ?  ":"  :  "";
  276.   *(array++) = setgame->plr2  ?   setgame->plr2->Name :
  277.                   (char *) GetChaosString(MSG_FREE_POINT_OUTPUT);
  278.   *array = (setgame->plr2 && setgame->colors)  ?
  279.             (char *) GetChaosString(MSG_COLORS_SET)  :  "";
  280.   return(0);
  281. }
  282. #ifdef AZTEC_C
  283. extern LONG MyDispGameFunc(struct SetGame *, char **);
  284. #asm
  285.             xref    _geta4
  286. _MyDispGameFunc:    move.l  a4,-(sp)
  287.             jsr     _geta4
  288.             move.l  a2,-(sp)
  289.             move.l  a1,-(sp)
  290.             jsr     _DispGameFunc
  291.             add.l   #8,sp
  292.             move.l  (sp)+,a4
  293.             rts
  294. #endasm
  295. #define DispGameFunc MyDispGameFunc
  296. #endif    /*  AZTEC_C */
  297. struct Hook GmStWnd_GmListDispHook =
  298. { NULL, NULL, (void *) DispGameFunc, NULL, NULL
  299. };
  300.  
  301.  
  302.  
  303.  
  304. #define ID_GmStWnd_Ok        8
  305. #define ID_GmStWnd_Cancel   9
  306. #define ID_GmStWnd_PlrLV    10
  307. #define ID_GmStWnd_GmDel    11
  308. #define ID_GmStWnd_GmLV     12
  309.  
  310. int GetSettings(int user)
  311.  
  312. { struct Player *plr;
  313.   ULONG open, signal;
  314.   int result = -1;
  315.   struct SetGame *sg;
  316.   APTR GmStWnd = NULL;        /*    Game set window             */
  317.   APTR GmStWnd_OkGad;        /*    Ok gadget (game set window)         */
  318.   APTR GmStWnd_CancelGad;   /*    Cancel gadget (game set window)     */
  319.   APTR GmStWnd_PlrList;     /*    player list (game set window)       */
  320.   APTR GmStWnd_PlrLV;        /*    player listview gad. (game set wnd.)*/
  321.   APTR GmStWnd_GmLV;        /*    game listview gadget (game set wnd.)*/
  322.   APTR GmStWnd_GmDel;        /*    delete button (game set window)     */
  323.   APTR GmStWnd_Clrs;        /*    Color mode gadget            */
  324.   char *CycleEntries[3];
  325.   int Ok_SC = *GetChaosString(MSG_OK_SC);
  326.   int Cancel_SC = *GetChaosString(MSG_CANCEL_SC);
  327.   int Delete_SC = *GetChaosString(BUTTON_DELETE_SC);
  328.  
  329.   extern struct Hook PlrSelWnd_PlrListDispHook;
  330.   extern struct Hook PlrSelWnd_PlrListCompHook;
  331.  
  332.  
  333.   if (!user)
  334.   { result = DoSetGames();
  335.     goto Terminate;
  336.   }
  337.  
  338.   CycleEntries[0] = (char *) GetChaosString(CYCLE_CHAOSCOLORS);
  339.   CycleEntries[1] = (char *) GetChaosString(CYCLE_USERCOLORS);
  340.   CycleEntries[2] = NULL;
  341.  
  342.   GmStWnd = WindowObject,
  343.         MUIA_Window_ID, MAKE_ID('G','M','S','T'),
  344.         MUIA_Window_Title, GetChaosString(WND_GAMESET_TITLE),
  345.         MUIA_Window_Width, MUIV_Window_Width_MinMax(50),
  346.         WindowContents, VGroup,
  347.             Child, HGroup,
  348.             Child, VGroup,
  349.                 Child, GmStWnd_PlrLV = ListviewObject,
  350.                 MUIA_Listview_List, GmStWnd_PlrList = ListObject,
  351.                     MUIA_List_Format, "",
  352.                     MUIA_List_DisplayHook, &PlrSelWnd_PlrListDispHook,
  353.                     MUIA_List_CompareHook, &PlrSelWnd_PlrListCompHook,
  354.                     InputListFrame,
  355.                 End,
  356.                 End,
  357.                 Child, GmStWnd_Clrs = Cycle(CycleEntries),
  358.              End,
  359.              Child, VGroup,
  360.                 MUIA_Weight, 400,
  361.                 Child, GmStWnd_GmLV = ListviewObject,
  362.                 MUIA_Listview_List, ListObject,
  363.                     MUIA_List_Format, ",P=\33c,,",
  364.                     MUIA_List_DisplayHook, &GmStWnd_GmListDispHook,
  365.                     InputListFrame,
  366.                 End,
  367.                 End,
  368.                 Child, HGroup,
  369.                 Child, HSpace(0),
  370.                 Child, GmStWnd_GmDel = KeyButton(GetChaosString(BUTTON_DELETE_TITLE), Delete_SC),
  371.                 End,
  372.              End,
  373.             End,
  374.             Child, HGroup,
  375.             MUIA_Group_SameSize, TRUE,
  376.             Child, GmStWnd_OkGad = KeyButton(GetChaosString(MSG_OK), Ok_SC),
  377.             Child, HSpace(0),
  378.             Child, GmStWnd_CancelGad = KeyButton(GetChaosString(MSG_CANCEL_INPUT), Cancel_SC),
  379.             End,
  380.         End,
  381.         End;
  382.  
  383.   if (!GmStWnd)
  384.   { return(-1);
  385.   }
  386.   DoMethod(App, OM_ADDMEMBER, GmStWnd);
  387.   DoMethod(GmStWnd, MUIM_Window_SetCycleChain, GmStWnd_PlrLV, GmStWnd_GmLV,
  388.        GmStWnd_GmDel, GmStWnd_OkGad, GmStWnd_CancelGad,
  389.        NULL);
  390.   set(GmStWnd, MUIA_Window_ActiveObject, GmStWnd_PlrLV);
  391.  
  392.   /*
  393.       Setting up the notification events for the game set window:
  394.       CloseWindow, Ok-, Cancel- and Delete-buttons and the listview
  395.       gadgets
  396.   */
  397.   DoMethod(GmStWnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App,
  398.        2, MUIM_Application_ReturnID, ID_GmStWnd_Cancel);
  399.   DoMethod(GmStWnd_CancelGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
  400.        MUIM_Application_ReturnID, ID_GmStWnd_Cancel);
  401.   DoMethod(GmStWnd, MUIM_Notify, MUIA_Window_InputEvent, "ctrl return",
  402.        App, 2, MUIM_Application_ReturnID, ID_GmStWnd_Ok);
  403.   DoMethod(GmStWnd_OkGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
  404.        MUIM_Application_ReturnID, ID_GmStWnd_Ok);
  405.   DoMethod(GmStWnd_GmDel, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
  406.        MUIM_Application_ReturnID, ID_GmStWnd_GmDel);
  407.   DoMethod(GmStWnd_PlrLV, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, App,
  408.        2, MUIM_Application_ReturnID, ID_GmStWnd_PlrLV);
  409.   DoMethod(GmStWnd_GmLV, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
  410.        App, 2, MUIM_Application_ReturnID, ID_GmStWnd_GmLV);
  411.  
  412.  
  413.   /*
  414.       Initialize the list of games
  415.   */
  416.   if (SetGames == NULL  &&  !InitSetGames())
  417.   { goto Terminate;
  418.   }
  419.   for (sg = (struct SetGame *) SetGames->mlh_Head;
  420.        sg->node.mln_Succ != NULL;
  421.        sg = (struct SetGame *) sg->node.mln_Succ)
  422.   { DoMethod(GmStWnd_GmLV, MUIM_List_Insert, &sg, 1, MUIV_List_Insert_Bottom);
  423.   }
  424.  
  425.  
  426.   /*
  427.       Initialize the player list
  428.   */
  429.   for (plr = (struct Player *) PlayerList.lh_Head;
  430.        plr->Tn_Node.ln_Succ != NULL;
  431.        plr = (struct Player *) plr->Tn_Node.ln_Succ)
  432.   { if ((plr->Flags & TNFLAGSF_WITHDRAWN)  ==  0)
  433.     { for (sg = (struct SetGame *) SetGames->mlh_Head;
  434.        sg->node.mln_Succ != NULL;
  435.        sg = (struct SetGame *) sg->node.mln_Succ)
  436.       { if (sg->plr1 == plr  ||  sg->plr2 == plr)
  437.     { break;
  438.     }
  439.       }
  440.       if (sg->node.mln_Succ ==  NULL)
  441.       { DoMethod(GmStWnd_PlrLV, MUIM_List_Insert, &plr, 1,
  442.          MUIV_List_Insert_Bottom);
  443.       }
  444.     }
  445.   }
  446.  
  447.  
  448.   /*
  449.       Open the window
  450.   */
  451.   set(GmStWnd_GmLV, MUIA_List_Active, MUIV_List_Active_Bottom);
  452.   set(GmStWnd, MUIA_Window_Open, TRUE);
  453.   get(GmStWnd, MUIA_Window_Open, &open);
  454.   if (!open)
  455.   { MUIError((char *) GetChaosString(ERRMSG_CANNOT_OPEN_WINDOW));
  456.     goto Terminate;
  457.   }
  458.  
  459.   /*
  460.       Wait for user actions
  461.   */
  462.   for(;;)
  463.   { int colors;
  464.  
  465.     switch(DoMethod(App, MUIM_Application_Input, &signal))
  466.     { case MUIV_Application_ReturnID_Quit:
  467.     if (TestSaved())
  468.     { exit(0);
  469.     }
  470.     break;
  471.       case ID_GmStWnd_Ok:
  472.     if ((result = DoSetGames())  ==  -1)
  473.     { break;
  474.     }
  475.     goto Terminate;
  476.       case ID_GmStWnd_Cancel:
  477.     goto Terminate;
  478.       case ID_GmStWnd_PlrLV:
  479.     /*
  480.         Get the active player
  481.     */
  482.     DoMethod(GmStWnd_PlrLV, MUIM_List_GetEntry,
  483.          MUIV_List_GetEntry_Active, &plr);
  484.     get(GmStWnd_Clrs, MUIA_Cycle_Active, &colors);
  485.  
  486.     if (!SetPlayer(plr, FALSE, colors))
  487.     { break;
  488.     }
  489.  
  490.     /*
  491.         Remove him from the list of players
  492.     */
  493.     DoMethod(GmStWnd_PlrLV, MUIM_List_Remove, MUIV_List_Remove_Active);
  494.  
  495.     sg = (struct SetGame *) SetGames->mlh_TailPred;
  496.     if (sg->plr2 == plr)
  497.     { DoMethod(GmStWnd_GmLV, MUIM_List_Remove, MUIV_List_Remove_Last);
  498.     }
  499.     DoMethod(GmStWnd_GmLV, MUIM_List_Insert, &sg, 1,
  500.          MUIV_List_Insert_Bottom);
  501.     set(GmStWnd_GmLV, MUIA_List_Active, MUIV_List_Active_Bottom);
  502.     break;
  503.       case ID_GmStWnd_GmDel:
  504.     /*
  505.         Get the active game from the list of games
  506.     */
  507.     DoMethod(GmStWnd_GmLV, MUIM_List_GetEntry,
  508.          MUIV_List_GetEntry_Active, &sg);
  509.     if (sg == NULL)
  510.     { break;
  511.     }
  512.  
  513.     /*
  514.         Remove it from the list
  515.     */
  516.     DoMethod(GmStWnd_GmLV, MUIM_List_Remove, MUIV_List_Remove_Active);
  517.     Remove((struct Node *) sg);
  518.  
  519.     /*
  520.         Add the players into the list of players
  521.     */
  522.     set(GmStWnd_PlrLV, MUIA_List_Quiet, TRUE);
  523.     DoMethod(GmStWnd_PlrLV, MUIM_List_Insert, &sg->plr1, 1,
  524.          MUIV_List_Insert_Sorted);
  525.     if (sg->plr2 != NULL)
  526.     { DoMethod(GmStWnd_PlrLV, MUIM_List_Insert, &sg->plr2, 1,
  527.            MUIV_List_Insert_Sorted);
  528.     }
  529.     set(GmStWnd_PlrLV, MUIA_List_Quiet, FALSE);
  530.     break;
  531.       case ID_GmStWnd_GmLV:
  532.     DoMethod(GmStWnd_GmLV, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
  533.          &sg);
  534.     set(GmStWnd_GmDel, MUIA_Disabled, sg == NULL);
  535.     break;
  536.     }
  537.  
  538.     if (signal)
  539.     { Wait(signal);
  540.     }
  541.   }
  542.  
  543.  
  544. Terminate:
  545.   if (GmStWnd)
  546.   { set(GmStWnd, MUIA_Window_Open, FALSE);
  547.     DoMethod(App, OM_REMMEMBER, GmStWnd);
  548.     MUI_DisposeObject(GmStWnd);
  549.   }
  550.   PutMemList(&GmMem);
  551.   SetGames = NULL;
  552.   return(result);
  553. }
  554. #endif    /*  AMIGA   */
  555.